package com.onesports.intelligent.k12.polarlight.service.order;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.onesports.framework.kit.common.util.ParamUtils;
import com.onesports.intelligent.k12.polarlight.domain.dto.sys.WxUserPurseChangeDTO;
import com.onesports.intelligent.k12.polarlight.domain.entity.market.Orders;
import com.onesports.intelligent.k12.polarlight.domain.entity.market.OrdersSub;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.Coach;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.Organization;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.OrganizationCampus;
import com.onesports.intelligent.k12.polarlight.enums.OrderSubTypeEnum;
import com.onesports.intelligent.k12.polarlight.enums.SysConfigTypeEnum;
import com.onesports.intelligent.k12.polarlight.enums.TradeTypeEnum;
import com.onesports.intelligent.k12.polarlight.mapper.market.OrdersMapper;
import com.onesports.intelligent.k12.polarlight.mapper.market.OrdersSubMapper;
import com.onesports.intelligent.k12.polarlight.mapper.organization.CoachMapper;
import com.onesports.intelligent.k12.polarlight.mapper.organization.OrganizationCampusMapper;
import com.onesports.intelligent.k12.polarlight.mapper.organization.OrganizationMapper;
import com.onesports.intelligent.k12.polarlight.service.sys.ConfigService;
import com.onesports.intelligent.k12.polarlight.service.wx.WxUserPurseService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

@Service
@RequiredArgsConstructor
public class OrdersSubService extends ServiceImpl<OrdersSubMapper, OrdersSub> {

    private final ConfigService configService;

    private final WxUserPurseService userPurseService;

    private final OrganizationMapper organizationMapper;

    private final OrganizationCampusMapper organizationCampusMapper;

    private final CoachMapper coachMapper;

    private final OrdersMapper ordersMapper;
    /**
     * 创建订单分账记录
     * @param order 订单
     */
    public void addSubOrder(Orders order){
        Long count = baseMapper.selectCount(new LambdaQueryWrapper<OrdersSub>().eq(OrdersSub::getOrdersId,order.getId()));
        if(count>0){
            return;
        }
        //分账逻辑：分两层分账，
        //第一层：团长+(运营团队+平台方)(剩余金额)
        //第二层：将运营团队分账金额再进行分账,分给教练+社区+运营团队(剩余金额)
        String headRatioStr =  configService.getValueByType(SysConfigTypeEnum.E);
        //团长分账比例
        BigDecimal headRatio = BigDecimal.ZERO;
        Coach coach = coachMapper.selectById(order.getCoachId());
        //教练分账比例
        BigDecimal coachRatio = coach.getSubRatio();
        // 运营团队分账比例
        Organization organization = organizationMapper.selectById(order.getOrganizationId());
        BigDecimal organizationRatio = organization.getSubRatio();
        // 社区分账比例
        OrganizationCampus organizationCampus = organizationCampusMapper.selectById(order.getCampusId());
        BigDecimal campusRatio = organizationCampus.getSubRatio();
        if(StringUtils.isNotBlank(headRatioStr)){
            headRatio = new BigDecimal(headRatioStr);
        }

        //团长分账
        OrdersSub headSub = add(order.getId(),calculation(order.getActuallyAmount(),headRatio),headRatio,OrderSubTypeEnum.HEAD);
        //团队分账总金额
        BigDecimal organizationLedger = calculation(order.getActuallyAmount().subtract(headSub.getSubLedger()),organizationRatio);
        //教练分账金额
        BigDecimal coachLedger = calculation(organizationLedger,coachRatio);
        //社区分账金额
        BigDecimal campusLedger = calculation(organizationLedger,campusRatio);
        //平台分账金额
        BigDecimal platformLedger = order.getActuallyAmount().subtract(headSub.getSubLedger()).subtract(organizationLedger);
        //团队分账金额
        organizationLedger = organizationLedger.subtract(coachLedger).subtract(campusLedger);

        OrdersSub organizationSub = add(order.getId(),organizationLedger,organizationRatio,OrderSubTypeEnum.ORGANIZATION);

        OrdersSub campusSub = add(order.getId(),campusLedger,campusRatio,OrderSubTypeEnum.CAMPUS);

        OrdersSub coachSub = add(order.getId(),coachLedger,coachRatio,OrderSubTypeEnum.COACH);

        OrdersSub platformSub = add(order.getId(),platformLedger,new BigDecimal(100).subtract(organizationRatio).subtract(headRatio),OrderSubTypeEnum.PLATFORM);

        List<OrdersSub> ordersSubs = Lists.newArrayList();
        ordersSubs.add(headSub);
        ordersSubs.add(organizationSub);
        ordersSubs.add(campusSub);
        ordersSubs.add(coachSub);
        ordersSubs.add(platformSub);
        saveBatch(ordersSubs);
    }

    public OrdersSub add(String orderId,BigDecimal ledger,BigDecimal ratio,OrderSubTypeEnum subType){
        OrdersSub ordersSub = new OrdersSub();
        ordersSub.setOrdersId(orderId);
        ordersSub.setSubLedger(ledger);
        ordersSub.setSubRatio(ratio);
        ordersSub.setSubType(subType.getValue());
        return ordersSub;
    }

    public BigDecimal calculation(BigDecimal amount,BigDecimal ratio){
        //换算百分比
        if(null==amount || amount.compareTo(BigDecimal.ZERO)<=0 || ratio.compareTo(BigDecimal.ZERO)<=0){
            return BigDecimal.ZERO;
        }
        ratio = ratio.divide(new BigDecimal(100), 2, RoundingMode.DOWN);
        return amount.multiply(ratio).setScale(2,RoundingMode.DOWN);
    }

    /**
     * 分佣金额分发
     * @param order 订单
     */
    public void subOrder(Orders order){
        if(order.getCommission()){
            return;
        }
        //分佣数据
        List<OrdersSub> headSub =  baseMapper.selectList(new QueryWrapper<OrdersSub>().lambda()
                .eq(OrdersSub::getOrdersId,order.getId())
                .in(OrdersSub::getSubType, OrderSubTypeEnum.HEAD.getValue(),OrderSubTypeEnum.COACH.getValue()));
        headSub.forEach(item->{
            if(item.getSubLedger().compareTo(BigDecimal.ZERO)>0){
                TradeTypeEnum tradeType = TradeTypeEnum.HEAD_SUB;
                String toSubUserId = order.getHeadId();
                if(OrderSubTypeEnum.COACH.getValue().equals(item.getSubType())){
                    tradeType = TradeTypeEnum.COACH_SUB;
                    Coach coach = coachMapper.selectById(order.getCoachId());
                    toSubUserId = coach.getWxUserId();
                }
                WxUserPurseChangeDTO dto = WxUserPurseChangeDTO.builder()
                        .tradeType(tradeType)
                        .wxUserId(toSubUserId)
                        .operateTime(new Date())
                        .amount(item.getSubLedger())
                        .orderNo(order.getOrderNo())
                        .income(true)
                        .build();
                userPurseService.inOrOutPurse(dto);
            }
        });

    }

}
